package util;

import java.io.IOException;

import org.newdawn.slick.Animation;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Music;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.loading.DeferredResource;
import org.newdawn.slick.loading.LoadingList;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

/**
 * Loads external files for the game.
 * @author VincentLy
 */
public class Loader extends BasicGameState{

	private DeferredResource res;
	private boolean loaded = false;
	
	public Loader(){super();}
	
	/**
	 * Deferred loading applied to images and music.
	 * @author VincentLy
	 */
	public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
		LoadingList.setDeferredLoading(true);
		Settings.bgm = new Music("res/sample.ogg");
		Settings.player = new Image("res/stand.png");
		Settings.walk1 = new Image("res/walk1.png");
		Settings.walk2 = new Image("res/walk2.png");
		Settings.walk3 = new Image("res/walk3.png");
		Settings.walk4 = new Image("res/walk4.png");
		Settings.jump = new Image("res/jump.png");
		Settings.crouch = new Image("res/crouch.png");
		Settings.shoot = new Image("res/shoot.png");
		Settings.portal = new Image("res/portalfin.png");
		Settings.enemy1 = new Image("res/goombareplace1.png");	
		Settings.enemy2 = new Image("res/goombareplace2.png");
		Settings.enemy3 = new Image("res/goombareplace3.png");
		Settings.bullet = new Image("res/bullet.png");
		Settings.texture = new Image("res/stage1texture.png");
		Settings.background = new Image("res/openingroom.png");
		Settings.gameover = new Image("res/gameover.png");
		Settings.door = new Image("res/door.png");		
		Settings.heaven = new Image("res/bulletheaven.png");
		Settings.save1 = new Image("res/save1.png");
		Settings.save2 = new Image("res/save2.png");
		Settings.save3 = new Image("res/save3.png");
		Settings.save4 = new Image("res/save4.png");
		Settings.save5 = new Image("res/save5.png");
		Settings.save6 = new Image("res/save6.png");
		Settings.save7 = new Image("res/save7.png");
		Settings.save8 = new Image("res/save8.png");
		Settings.save9 = new Image("res/save9.png");
		Settings.hpbar = new Image("res/healthbar.png");
		Settings.player = Settings.player.getScaledCopy((int) (Settings.playerSize*Settings.playerRatio),Settings.playerSize);
		Settings.walk1 = Settings.walk1.getScaledCopy((int) (Settings.playerSize*Settings.playerRatio),Settings.playerSize);
		Settings.walk2 = Settings.walk2.getScaledCopy((int) (Settings.playerSize*Settings.playerRatio),Settings.playerSize);
		Settings.walk3 = Settings.walk3.getScaledCopy((int) (Settings.playerSize*Settings.playerRatio),Settings.playerSize);
		Settings.walk4 = Settings.walk4.getScaledCopy((int) (Settings.playerSize*Settings.playerRatio),Settings.playerSize);
		Settings.jump = Settings.jump.getScaledCopy((int) (Settings.playerSize*Settings.playerRatio),Settings.playerSize);
		Settings.crouch = Settings.crouch.getScaledCopy((int) (Settings.playerSize*.75),Settings.playerSize);
		Settings.bullet = Settings.bullet.getScaledCopy(20,10);
		Settings.portal = Settings.portal.getScaledCopy(100,86);
		Settings.shoot = Settings.shoot.getScaledCopy((int) (Settings.playerSize*.81),Settings.playerSize);
		Settings.gameover = Settings.gameover.getScaledCopy(430,600);
		Settings.door = Settings.door.getScaledCopy(100,Settings.playerSize);
		Settings.heaven = Settings.heaven.getScaledCopy(300,150);
		Settings.backjump = Settings.jump.getFlippedCopy(true,false);
		Settings.backcrouch = Settings.crouch.getFlippedCopy(true,false);
		Settings.backshoot = Settings.shoot.getFlippedCopy(true,false);
		Settings.backbullet = Settings.bullet.getFlippedCopy(true,false);
		Settings.save1 = Settings.save1.getScaledCopy(185,100);
		Settings.save2 = Settings.save2.getScaledCopy(185,100);
		Settings.save3 = Settings.save3.getScaledCopy(185,100);
		Settings.save4 = Settings.save4.getScaledCopy(185,100);
		Settings.save5 = Settings.save5.getScaledCopy(185,100);
		Settings.save6 = Settings.save6.getScaledCopy(185,100);
		Settings.save7 = Settings.save7.getScaledCopy(185,100);
		Settings.save8 = Settings.save8.getScaledCopy(185,100);
		Settings.save9 = Settings.save9.getScaledCopy(185,100);
		Settings.hpbar = Settings.hpbar.getScaledCopy(177,75);
		Settings.enemy1 = Settings.enemy1.getScaledCopy((int) (Settings.playerSize*.92),Settings.playerSize);
		Settings.enemy2 = Settings.enemy2.getScaledCopy((int) (Settings.playerSize*.92),Settings.playerSize);
		Settings.enemy3 = Settings.enemy3.getScaledCopy((int) (Settings.playerSize*.92),Settings.playerSize);
		Settings.pause = new Image(800,600);
		Settings.save = new Animation(new Image[]{Settings.save1,Settings.save2,Settings.save3,Settings.save4,Settings.save5,Settings.save6,Settings.save7,Settings.save8,Settings.save9},200);
		Settings.enemy = new Animation(new Image[]{Settings.enemy1,Settings.enemy2,Settings.enemy3},200);
		Settings.fwd = new Animation(new Image[]{Settings.walk1,Settings.walk2,Settings.walk3,Settings.walk4},200);
		Settings.bwd = new Animation(new Image[]{Settings.walk1.getFlippedCopy(true,false),Settings.walk2.getFlippedCopy(true,false),Settings.walk3.getFlippedCopy(true,false),Settings.walk4.getFlippedCopy(true,false)},200);
	}
	
	/**
	 * Updates the loading bar, noticeable when there are a lot of resources.
	 * @author VincentLy
	 */
	public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
		if (res != null) {
			try {res.load();} 
			catch (IOException e) {System.out.println("Load fail.");}			
			res = null;
		}		
		if (LoadingList.get().getRemainingResources() > 0) 
			res = LoadingList.get().getNext();
		else if(!loaded){
			loaded = true;	
			Settings.bgm.loop();
			sbg.enterState(Settings.smID);
		}	
	}
	
	/**
	 * Draws the status bar.
	 * @author VincentLy
	 */
	public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
		g.setColor(Color.white);
		if (res!= null) 
			g.drawString("Loading",300,250);		
		int total = LoadingList.get().getTotalResources();
		int rem = total - LoadingList.get().getRemainingResources();
		g.fillRect(300,290,(float)rem/(float)total*200,20);
		g.drawRect(300,290,200,20);
	}

	/**
	 * @return id
	 * @author VincentLy
	 */
	public int getID() {return Settings.mlID;}	
}